package com.cnbot.toolkit.bitmap;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextPaint;
import android.util.Base64;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * @author wzz
 */
public final class BitmapUtils {

	private BitmapUtils() {}

	public static Bitmap getFitSampleBitmap(String imagePath, int width, int height) {
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
		options.inPreferredConfig = Bitmap.Config.ARGB_8888;
		BitmapFactory.decodeFile(imagePath, options);
		options.inSampleSize = getFitInSampleSize(width, height, options);
		options.inJustDecodeBounds = false;
		Bitmap bitmap = BitmapFactory.decodeFile(imagePath, options);
		if (bitmap != null) {
			bitmap = getSmallImage(bitmap, width, height, true);
			int bitmapDegree = getBitmapDegree(imagePath);
			bitmap = roateBitmap(bitmap, (float) bitmapDegree, true);
		}
		return bitmap;
	}

	public static Bitmap getOriginBitmap(String imagePath) {
		Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
		if (bitmap != null) {
			int bitmapDegree = getBitmapDegree(imagePath);
			bitmap = roateBitmap(bitmap, (float) bitmapDegree, true);
		}
		return bitmap;
	}

	public static Bitmap getSmallImage(Bitmap bitmap, int mWidth, int mHight, boolean isRecycle) {
		int w = bitmap.getWidth();
		int h = bitmap.getHeight();
		float scaleH = (float) mHight / (float) h;
		float scaleW = (float) mWidth / (float) w;
		Matrix matrix = new Matrix();
		float min = Math.min(scaleH, scaleW);
		if (min >= 1.0F) {
			return bitmap;
		} else {
			matrix.postScale(min, min);
			return createBitmapByMatrix(bitmap, matrix, true, isRecycle);
		}
	}

	public static int getFitInSampleSize(int reqWidth, int reqHeight, BitmapFactory.Options options) {
		int w = options.outWidth;
		int h = options.outHeight;
		int zoomRatio = 1;
		if (w > h && w > reqWidth) {
			zoomRatio = w / reqWidth;
		} else if (w < h && h > reqHeight) {
			zoomRatio = h / reqHeight;
		}
		return zoomRatio;
	}

	public static Bitmap createBitmap(int w, int h) {
		return Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
	}

	public static Bitmap createBitmapByMatrix(Bitmap source, Matrix m, boolean filter, boolean isRecycle) {
		Bitmap result = Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), m, filter);
		if (isRecycle && result != source) {
			recycleBitmap(source);
		}
		return result;
	}

	public static String saveBitmap(Context context, Bitmap b, String name) {
		return saveBitmap(context, b, name, Bitmap.CompressFormat.JPEG);
	}

	public static String saveBitmap(Context context, Bitmap b, String name, Bitmap.CompressFormat format) {
		File file = new File(name);
		File photoFile = savePhotoToSDCard(b, file.getParent(), file.getName(), format);
		try {
			MediaStore.Images.Media.insertImage(context.getContentResolver(), file.getParent(), file.getName(), null);
		} catch (FileNotFoundException var8) {
			var8.printStackTrace();
		}
		Intent intent = new Intent("android.intent.action.MEDIA_SCANNER_SCAN_FILE");
		Uri uri = Uri.fromFile(photoFile);
		intent.setData(uri);
		context.sendBroadcast(intent);
		assert photoFile != null;
		return photoFile.getAbsolutePath();
	}

	public static File savePhotoToSDCard(Bitmap photoBitmap, String path, String photoName) {
		return savePhotoToSDCard(photoBitmap, path, photoName, Bitmap.CompressFormat.JPEG);
	}

	private static File savePhotoToSDCard(Bitmap photoBitmap, String path, String photoName, Bitmap.CompressFormat format) {
		if (checkSDCardAvailable()) {
			File dir = new File(path);
			if (!dir.exists()) {
				dir.mkdirs();
			}
			File photoFile = new File(path, photoName);
			FileOutputStream fileOutputStream = null;
			File var7;
			try {
				fileOutputStream = new FileOutputStream(photoFile);
				if (photoBitmap.compress(format, 100, fileOutputStream)) {
					fileOutputStream.flush();
					fileOutputStream.close();
				}
				var7 = photoFile;
			} catch (FileNotFoundException var19) {
				photoFile.delete();
				var19.printStackTrace();
				return null;
			} catch (IOException var20) {
				photoFile.delete();
				var20.printStackTrace();
				return null;
			} finally {
				try {
					if (fileOutputStream != null) {
						fileOutputStream.close();
					}
				} catch (IOException var18) {
					var18.printStackTrace();
				}
			}
			return var7;
		} else {
			return null;
		}
	}

	public static boolean checkSDCardAvailable() {
		return "mounted".equals(Environment.getExternalStorageState());
	}

	public static Bitmap getScaleBitmap(Bitmap bitmap, float rate, boolean isRecycle) {
		int w = bitmap.getWidth();
		int h = bitmap.getHeight();
		Matrix matrix = new Matrix();
		matrix.postScale(rate, rate);
		return createBitmapByMatrix(bitmap, matrix, true, isRecycle);
	}

	public static Bitmap getFilpBitmap(Bitmap bitmap, boolean isRecycle) {
		Matrix matrix = new Matrix();
		matrix.postScale(-1.0F, 1.0F);
		return createBitmapByMatrix(bitmap, matrix, true, isRecycle);
	}

	public static Bitmap getFilpBitmap(Bitmap bitmap, float angle, boolean isRecycle) {
		Matrix matrix = new Matrix();
		matrix.postScale(-1.0F, 1.0F);
		matrix.postRotate(angle);
		return createBitmapByMatrix(bitmap, matrix, true, isRecycle);
	}

	public static Bitmap getTBFilpBitmap(Bitmap bitmap, float mAngle, boolean isRecycle) {
		Matrix matrix = new Matrix();
		matrix.postScale(1.0F, -1.0F);
		matrix.postRotate(mAngle);
		return createBitmapByMatrix(bitmap, matrix, true, isRecycle);
	}

	public static Bitmap roateBitmap(Bitmap currentSelBitmap, float angle, boolean isRecycle) {
		Matrix matrix = new Matrix();
		matrix.postRotate(angle);
		return createBitmapByMatrix(currentSelBitmap, matrix, false, isRecycle);
	}

	public static Bitmap getSmallBitmapByX(Bitmap bitmap, int mWidth, boolean isRecycle) {
		int w = bitmap.getWidth();
		int h = bitmap.getHeight();
		Matrix matrix = new Matrix();
		float scale2 = (float) mWidth / (float) w;
		matrix.postScale(scale2, scale2);
		return createBitmapByMatrix(bitmap, matrix, true, isRecycle);
	}

	public static Bitmap getSmallBitmapByY(Bitmap bitmap, int mHight, boolean isRecycle) {
		int w = bitmap.getWidth();
		int h = bitmap.getHeight();
		Matrix matrix = new Matrix();
		float scale2 = (float) mHight / (float) h;
		matrix.postScale(scale2, scale2);
		return createBitmapByMatrix(bitmap, matrix, true, isRecycle);
	}

	public static Bitmap getSmallBitmapByXY(Bitmap bitmap, int mWidth, int mHight, boolean isRecycle) {
		int w = bitmap.getWidth();
		int h = bitmap.getHeight();
		float scaleH = (float) mHight / (float) h;
		float scaleW = (float) mWidth / (float) w;
		Matrix matrix = new Matrix();
		float min = Math.min(scaleH, scaleW);
		matrix.postScale(min, min);
		return createBitmapByMatrix(bitmap, matrix, true, isRecycle);
	}

	public static Bitmap adjustViewAndBitmap(Bitmap bmp, View multipleLayersView, boolean isRecycle) {
		ViewGroup.LayoutParams layoutParams = multipleLayersView.getLayoutParams();
		int width = multipleLayersView.getMeasuredWidth();
		int height = multipleLayersView.getMeasuredHeight();
		int bitmapW = bmp.getWidth();
		int bitmapH = bmp.getHeight();
		float f1 = (float) width / (float) bitmapW;
		float f2 = (float) height / (float) bitmapH;
		Bitmap result;
		if (f2 > f1) {
			result = getSmallBitmapByX(bmp, width, isRecycle);
			layoutParams.height = result.getHeight();
			layoutParams.width = result.getWidth();
		} else {
			result = getSmallBitmapByY(bmp, height, isRecycle);
			layoutParams.height = result.getHeight();
			layoutParams.width = result.getWidth();
		}
		multipleLayersView.setLayoutParams(layoutParams);
		return result;
	}

	public static Bitmap createTxtBitmap(String str, Typeface font, int color) {
		TextPaint textPaint = new TextPaint();
		textPaint.setColor(color);
		textPaint.setTypeface(font);
		textPaint.setTextSize(300.0F);
		textPaint.setTextAlign(Paint.Align.LEFT);
		textPaint.setFakeBoldText(true);
		Paint.FontMetricsInt fontMetrics = textPaint.getFontMetricsInt();
		String[] split = str.split("\n");
		int maxIndex = 0;
		int i;
		for (i = 0; i < split.length; ++i) {
			if (split[maxIndex].length() < split[i].length()) {
				maxIndex = i;
			}
		}
		i = (int) textPaint.measureText(split[maxIndex]);
		int imageHeight = fontMetrics.descent + Math.abs(fontMetrics.ascent);
		int baseLine = 0 - fontMetrics.ascent;
		Bitmap bmp = Bitmap.createBitmap(i, imageHeight * split.length, Bitmap.Config.ARGB_8888);
		Canvas canvasTemp = new Canvas(bmp);
		canvasTemp.drawColor(0);
		if ("".equals(str)) {
			return bmp;
		} else {
			for (int ii = 0; ii < split.length; ++ii) {
				canvasTemp.drawText(split[ii], 0.0F, (float) (imageHeight * ii + baseLine), textPaint);
			}
			return bmp;
		}
	}

	public static Bitmap getWaterMask(Bitmap bitmap, Bitmap maskBitmap, boolean recycle) {
		Bitmap bmp = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
		Canvas canvasTemp = new Canvas(bmp);
		canvasTemp.drawColor(0);
		int pading = (int) ((double) bitmap.getWidth() * 0.025D);
		int newWidth = bitmap.getWidth() / 8;
		float rate = (float) newWidth / (float) maskBitmap.getWidth();
		int left = bitmap.getWidth() - newWidth - pading;
		int right = bitmap.getWidth() - pading;
		int top = bitmap.getHeight() - (int) ((float) maskBitmap.getHeight() * rate) - pading;
		int bottom = bitmap.getHeight() - pading;
		canvasTemp.setDrawFilter(new PaintFlagsDrawFilter(0, 3));
		canvasTemp.drawBitmap(bitmap, 0.0F, 0.0F, null);
		canvasTemp.drawBitmap(maskBitmap, new Rect(0, 0, maskBitmap.getWidth(), maskBitmap.getHeight()), new Rect(left, top, right, bottom), null);
		if (recycle) {
			recycleBitmap(bitmap);
		}
		return bmp;
	}

	public static void recycleBitmap(Bitmap bitmap) {
		if (bitmap != null && !bitmap.isRecycled()) {
			bitmap.recycle();
		}
	}

	public static int getBitmapDegree(String path) {
		short degree = 0;
		try {
			ExifInterface exifInterface = new ExifInterface(path);
			int orientation = exifInterface.getAttributeInt("Orientation", 1);
			switch (orientation) {
			case 3:
				degree = 180;
				break;
			case 6:
				degree = 90;
				break;
			case 8:
				degree = 270;
				break;
			default:
				break;
			}
		} catch (IOException var4) {
			var4.printStackTrace();
		}
		return degree;
	}

	public static int[] getBitmapOffset(ImageView imageView, boolean includeLayout) {
		int[] offset = new int[2];
		float[] values = new float[9];
		Matrix matrix = imageView.getImageMatrix();
		matrix.getValues(values);
		offset[0] = (int) values[2];
		offset[1] = (int) values[5];
		if (includeLayout) {
			ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) imageView.getLayoutParams();
			int paddingTop = imageView.getPaddingTop();
			int paddingLeft = imageView.getPaddingLeft();
			offset[0] += paddingLeft + params.leftMargin;
			offset[1] += paddingTop + params.topMargin;
		}
		return offset;
	}

	public static String bitmapToBase64(Bitmap bitmap) {
		String result = null;
		ByteArrayOutputStream baos = null;
		try {
			if (bitmap != null) {
				baos = new ByteArrayOutputStream();
				bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
				baos.flush();
				baos.close();
				byte[] bitmapBytes = baos.toByteArray();
				result = Base64.encodeToString(bitmapBytes, 0);
			}
		} catch (IOException var12) {
			var12.printStackTrace();
		} finally {
			try {
				if (baos != null) {
					baos.flush();
					baos.close();
				}
			} catch (IOException var11) {
				var11.printStackTrace();
			}

		}
		return result;
	}

	public static Bitmap base64ToBitmap(String base64Data) {
		byte[] bytes = Base64.decode(base64Data, 0);
		return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
	}



	private static int mix(int crBack, int crForeground) {
		int rBack = Color.red(crBack);
		int gBack = Color.green(crBack);
		int bBack = Color.blue(crBack);
		int aForeground = Color.alpha(crForeground);
		int rForeground = Color.red(crForeground);
		int gForeground = Color.green(crForeground);
		int bForeground = Color.blue(crForeground);
		return Color.rgb((int) ((float) rForeground * ((float) aForeground / 255.0F) + (float) rBack * (1.0F - (float) aForeground / 255.0F)),
				(int) ((float) gForeground * ((float) aForeground / 255.0F) + (float) gBack * (1.0F - (float) aForeground / 255.0F)),
				(int) ((float) bForeground * ((float) aForeground / 255.0F) + (float) bBack * (1.0F - (float) aForeground / 255.0F)));
	}

	public static Point getPathBitmapSize(String path) {
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
		BitmapFactory.decodeFile(path, options);
		return new Point(options.outWidth, options.outHeight);
	}

}
